package swing.frame;

import api.DictionaryApi;
import beans.Meaning;
import beans.Word;
import client.UserSession;
import com.alibaba.fastjson.JSONArray;
import http.Response;
import model.ApiResultModel;
import model.SearchResultModel;
import myException.ServerConnectException;
import swing.BaseFrame;
import swing.FrameManager;
import swing.dialog.UpdateWordDialog;
import swing.dialog.MeaningDetailDialog;
import swing.dialog.WordDetailDialog;
import utils.CommonUtils;

import javax.swing.*;
import javax.swing.border.EtchedBorder;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.List;

/**
 * 程序主界面
 */
public class MainFrame extends BaseFrame {

    public final static String frameTitle = "开源词典";

    //程序主界面组件容器
    public JPanel mainPanel;

    //个人主页按钮
    private JButton profileButton;

    //搜索
    private JTextField searchTextField;
    private JButton searchButton;
    //搜索提示
    private JList<String> searchHintListComp;
    private DefaultListModel<String> searchHintListModel;
    private final static int SEARCH_HINT_NUM = 10; //最多显示的提示条数

    //搜索结果展示
    private JLabel wordText;
    private JList<String> meaningListComp;
    private DefaultListModel<String> meaningListModel;
    //当前界面显示的单词
    private Word currentWord;
    private List<Meaning> currentMeaningList;

    //右侧最近新增单词列表
    private JLabel newWordStaticText;
    private JList<String> newWordListComp;
    private DefaultListModel<String> newWordListModel;
    private List<Word> newWordList = new ArrayList<>();
    private final static int NEW_WORD_NUM = 10;

    //添加单词
    private JButton addWordButton;

    //菜单
    private JPopupMenu meaningMenu;
    private JPopupMenu wordMenu;

    public MainFrame() {
        super();
        loadData();
    }

//组件初始化代码
//----------------------------------------------------------------------------------------------------------------------

    @Override
    protected void initFrame() {
        this.setTitle(frameTitle);
        mainPanel = new JPanel();
        mainPanel.setLayout(null);
        this.setContentPane(mainPanel);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setPreferredSize(new Dimension(950, 600));
        this.setResizable(false);
        this.pack();
        this.setLocationRelativeTo(null);
    }

    @Override
    protected void initAllComponent() {
        mainPanel.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                meaningListComp.clearSelection();
                newWordListComp.clearSelection();
            }
        });
        //搜索框
        searchTextField = new JTextField();
        searchTextField.setBounds(80, 20, 580,30);
        searchTextField.setFont(new Font("宋体", Font.PLAIN, 16));
        searchTextField.addKeyListener(new KeyAdapter() {
            @Override
            public void keyTyped(KeyEvent e) {
                if(e.getKeyChar()==KeyEvent.VK_ENTER) {
                    searchWord(searchTextField.getText().trim());
                }
            }
        });
        searchTextField.getDocument().addDocumentListener(new DocumentListener() {
            @Override
            public void insertUpdate(DocumentEvent e) {
                String prefix = searchTextField.getText().trim();
                //TODO 自己实现一个线程池或者一个可复用的线程
                new Thread(() -> {
                    flushSearchHint(prefix);
                }).start();
            }

            @Override
            public void removeUpdate(DocumentEvent e) {
                String prefix = searchTextField.getText().trim();
                new Thread(() -> {
                    flushSearchHint(prefix);
                }).start();
            }

            @Override
            public void changedUpdate(DocumentEvent e) {

            }
        });
        //检索按钮
        searchButton = new JButton();
        searchButton.setBounds(670, 20, 100,30);
        searchButton.setText("检索");
        searchButton.addActionListener(listener -> {
            searchWord(searchTextField.getText().trim());
        });
        //搜索提示
        searchHintListComp = new JList<>();
        searchHintListModel = new DefaultListModel<>();
        searchHintListComp.setBounds(80, 48, 580, 0);
        searchHintListComp.setFont(new Font("宋体", Font.PLAIN, 16));
        searchHintListComp.setModel(searchHintListModel);
        searchHintListComp.setBorder(new EtchedBorder());
        Color color = new Color(240, 248, 255);
//        Color color = new Color(224, 255, 255);
        searchHintListComp.setBackground(color);
        searchHintListComp.addMouseListener(new MouseListener() {
            @Override
            public void mouseClicked(MouseEvent e) {
                int index = searchHintListComp.locationToIndex(e.getPoint());
                searchHintListComp.setSelectedIndex(index);
                String wordStr = searchHintListModel.get(index);
                searchWord(wordStr);
                searchTextField.setText(wordStr);
                searchHintListComp.setSize(580, 0);
            }

            @Override
            public void mousePressed(MouseEvent e) {

            }

            @Override
            public void mouseReleased(MouseEvent e) {

            }

            @Override
            public void mouseEntered(MouseEvent e) {
                int index = searchHintListComp.locationToIndex(e.getPoint());
                searchHintListComp.setSelectedIndex(index);
            }

            @Override
            public void mouseExited(MouseEvent e) {
                searchHintListComp.clearSelection();
                searchHintListComp.setSize(580, 0);
            }
        });
        searchHintListComp.addMouseMotionListener(new MouseAdapter() {
            @Override
            public void mouseMoved(MouseEvent e) {
                int index = searchHintListComp.locationToIndex(e.getPoint());
                searchHintListComp.setSelectedIndex(index);
                super.mouseMoved(e);
            }
        });
        //个人主页按钮
        profileButton = new JButton();
        profileButton.setBounds(857, 8, 30, 30);
        profileButton.setFocusPainted(false);
        profileButton.addActionListener(listener -> {
            FrameManager.reverseProfileFrameState(this);
        });
        ImageIcon profileIcon = new ImageIcon(CommonUtils.getFileUrl("img/profile_button.png"));
        profileIcon.setImage(profileIcon.getImage().getScaledInstance(27, 27,Image.SCALE_DEFAULT ));
        profileButton.setIcon(profileIcon);
        //显示的单词
        wordText = new JLabel();
        wordText.setBounds(80, 75, 500, 50);
        Font wordTextFont = new Font("宋体", Font.BOLD,30);
        wordText.setFont(wordTextFont);
        wordText.addMouseListener(new MouseListener() {
            @Override
            public void mouseClicked(MouseEvent e) {

            }

            @Override
            public void mousePressed(MouseEvent e) {
                // 如果是鼠标右键，则显示弹出菜单
                if (e.isMetaDown()) {
                    wordMenu.show(e.getComponent(), e.getX(), e.getY());
                }
            }

            @Override
            public void mouseReleased(MouseEvent e) {

            }

            @Override
            public void mouseEntered(MouseEvent e) {
                Color wordTextColor = new Color(30, 144, 255);
                wordText.setForeground(wordTextColor);
            }

            @Override
            public void mouseExited(MouseEvent e) {
                wordText.setForeground(Color.BLACK);
            }
        });
        initWordMenu();
        //单词含义列表
        meaningListComp = new JList<>();
        meaningListModel = new DefaultListModel<>();
        meaningListComp.setBounds(90, 145, 500, 280);
        meaningListComp.setModel(meaningListModel);
        Font meaningFont = new Font("宋体", Font.PLAIN,20);
        meaningListComp.setFont(meaningFont);
        meaningListComp.setBackground(mainPanel.getBackground());
        meaningListComp.addMouseListener(new MouseAdapter() {
            @Override
            public void mousePressed(MouseEvent e) {
                int index = meaningListComp.locationToIndex(e.getPoint());
                meaningListComp.setSelectedIndex(index);
                // 如果是鼠标右键，则显示弹出菜单
                if (e.isMetaDown()) {
                    meaningMenu.show(e.getComponent(), e.getX(), e.getY());
                }
            }
        });
        initMeaningMenu();
        //"最近新增"静态文本
        newWordStaticText = new JLabel("最近新增");
        newWordStaticText.setBounds(675, 85, 130, 40);
        newWordStaticText.setFont(new Font("宋体", Font.BOLD,17));
        //最近新增单词列表
        newWordListComp = new JList<>();
        newWordListModel = new DefaultListModel<>();
        newWordListComp.setBounds(675, 140, 200, 280);
        newWordListComp.setModel(newWordListModel);
        newWordListComp.setFont(new Font("Calibri Light", Font.PLAIN, 18));
        newWordListComp.setBackground(mainPanel.getBackground());
        newWordListComp.addMouseListener(new MouseListener() {
            @Override
            public void mouseClicked(MouseEvent e) {
                int index = newWordListComp.locationToIndex(e.getPoint());
                newWordListComp.setSelectedIndex(index);
                flushWord(newWordList.get(index).getId());
            }

            @Override
            public void mousePressed(MouseEvent e) {

            }

            @Override
            public void mouseReleased(MouseEvent e) {

            }

            @Override
            public void mouseEntered(MouseEvent e) {
                int index = newWordListComp.locationToIndex(e.getPoint());
                newWordListComp.setSelectedIndex(index);
            }

            @Override
            public void mouseExited(MouseEvent e) {
                newWordListComp.clearSelection();
            }
        });
        newWordListComp.addMouseMotionListener(new MouseAdapter() {
            @Override
            public void mouseMoved(MouseEvent e) {
                int index = newWordListComp.locationToIndex(e.getPoint());
                newWordListComp.setSelectedIndex(index);
                super.mouseMoved(e);
            }
        });
        //添加单词按钮
        addWordButton = new JButton("+ 添加单词");
        addWordButton.setBounds(670, 450, 130,40);
        Font addWordFont = new Font("宋体", Font.BOLD,17);
        addWordButton.setFont(addWordFont);
        addWordButton.addActionListener(e -> {
            UpdateWordDialog addWordDialog = new UpdateWordDialog(this);
            long result = addWordDialog.showDialog();
            if (result > 0) {
                loadNewWordList();
                flushWord(result);
            }
        });
    }

    @Override
    protected void addAllComponent() {
        mainPanel.add(profileButton);
        mainPanel.add(searchTextField);
        mainPanel.add(searchButton);
        mainPanel.add(searchHintListComp);
        mainPanel.add(wordText);
        mainPanel.add(meaningListComp);
        mainPanel.add(addWordButton);
        mainPanel.add(newWordStaticText);
        mainPanel.add(newWordListComp);
    }

    /**
     * 设置单词含义右击菜单
     */
    private void initMeaningMenu() {
        meaningMenu = new JPopupMenu();
        JMenuItem viewDetailsItem = new JMenuItem("查看详情");
        viewDetailsItem.addActionListener(listener -> {
            int selectMeaningIndex = meaningListComp.getSelectedIndex();
            Meaning meaning = currentMeaningList.get(selectMeaningIndex);
            new MeaningDetailDialog(this, meaning).setVisible(true);
        });
        JMenuItem updateMeaningItem = new JMenuItem("修改");
        updateMeaningItem.addActionListener(listener -> {
            int selectMeaningIndex = meaningListComp.getSelectedIndex();
            Meaning meaning = currentMeaningList.get(selectMeaningIndex);
            UpdateWordDialog updateMeaningDialog = new UpdateWordDialog(this, UpdateWordDialog.UPDATE_MEANING, wordText.getText(), meaning);
            long result = updateMeaningDialog.showDialog();
            if (result > 0) flushWord(currentWord.getId());
        });
        JMenuItem deleteMeaningItem = new JMenuItem("删除");
        deleteMeaningItem.addActionListener(listener -> {
            int selectMeaningIndex = meaningListComp.getSelectedIndex();
            Meaning meaning = currentMeaningList.get(selectMeaningIndex);
            if (showConfirmDialog("删除提示", "确认删除此单词释义吗？\n" + meaning.getWord_meaning()) == JOptionPane.OK_OPTION) {
                deleteMeaning(selectMeaningIndex, meaning.getId());
            }
        });
        meaningMenu.add(viewDetailsItem);
        meaningMenu.add(updateMeaningItem);
        meaningMenu.add(deleteMeaningItem);
    }

    /**
     * 设置单词右击菜单
     */
    private void initWordMenu() {
        wordMenu = new JPopupMenu();
        //选项-查看详情
        JMenuItem viewDetailsItem = new JMenuItem("查看详情");
        viewDetailsItem.addActionListener(e -> {
            new WordDetailDialog(this, currentWord).setVisible(true);
        });
        //选项-添加释义
        JMenuItem addMeaningItem = new JMenuItem("添加释义");
        addMeaningItem.addActionListener(e -> {
            UpdateWordDialog addMeaningDialog = new UpdateWordDialog(this, UpdateWordDialog.ADD_MEANING, wordText.getText());
            long result = addMeaningDialog.showDialog();
            if (result > 0) flushWord(result);
        });
        //选项-删除单词
        JMenuItem deleteWordItem = new JMenuItem("删除单词");
        deleteWordItem.addActionListener(listener -> {
            if (showConfirmDialog("删除提示", "确认删除此单词吗？\n " + wordText.getText()) == JOptionPane.OK_OPTION) {
                long word_id = currentWord.getId();
                deleteWord(word_id);
            }
        });
        wordMenu.add(viewDetailsItem);
        wordMenu.add(addMeaningItem);
        wordMenu.add(deleteWordItem);
    }

    private void loadData() {
        loadNewWordList();
        if (!newWordList.isEmpty()) {
            flushWord(newWordList.get(0).getId());
        }
    }

//事件响应方法代码
//----------------------------------------------------------------------------------------------------------------------

    /**
     * 刷新搜索提示列表
     */
    private void flushSearchHint(String prefix) {
        if (prefix.isEmpty()) {
            searchHintListComp.setSize(580, 0);
            searchHintListModel.removeAllElements();
            return;
        }
        try {
            Response response = DictionaryApi.get_search_hint(UserSession.LoginUser(), SEARCH_HINT_NUM, prefix);
            ApiResultModel apiResultModel = ApiResultModel.fromJson(response.getBody());
            List<String> resultList = ((JSONArray)apiResultModel.getResult()).toJavaList(String.class);
            searchHintListComp.setSize(580, resultList.size() * 28);
            searchHintListModel.removeAllElements();
            for (String hint : resultList) {
                searchHintListModel.addElement(hint);
            }
        } catch (ServerConnectException e) {
            e.printStackTrace();
        }
    }

    /**
     * 刷新主界面显示的单词
     */
    private void flushWord(long word_id) {
        try {
            Response response = DictionaryApi.search_word(UserSession.LoginUser(), word_id, "");
            if (response.getStatus_code() != Response.OK) {
                return;
            }
            ApiResultModel<SearchResultModel> apiResult = ApiResultModel.fromJson(response.getBody(), SearchResultModel.class);
            if (apiResult.getCode() == ApiResultModel.SUCCESS_CODE) {
                currentWord =  apiResult.getResult().getWord();
                currentMeaningList = apiResult.getResult().getWordMeaningList();
                meaningListModel.removeAllElements();
                wordText.setText(currentWord.getWord_string());
                for (Meaning meaning : currentMeaningList) {
                    meaningListModel.addElement(meaning.getWord_meaning());
                }
            }
        } catch (ServerConnectException e) {
            showMessageDialog("服务器连接失败！");
        }
    }

    private void searchWord(String searchText) {
        if (searchText.isEmpty()) {
            showMessageDialog("请输入要检索的单词");
            searchTextField.setText("");
            searchTextField.requestFocus();
            return;
        }
        try {
            Response response = DictionaryApi.search_word(UserSession.LoginUser(), 0, searchText);
            if (response.getStatus_code() != Response.OK) {
                showMessageDialog(response.getStatus_code() + " " + response.getStatus_description());
                return;
            }
            ApiResultModel<SearchResultModel> apiResult = ApiResultModel.fromJson(response.getBody(), SearchResultModel.class);
            if (apiResult.getCode() == ApiResultModel.FAIL_CODE) {
                showMessageDialog(apiResult.getMessage());
                return;
            }
            currentWord =  apiResult.getResult().getWord();
            currentMeaningList = apiResult.getResult().getWordMeaningList();
            meaningListModel.removeAllElements();
            wordText.setText(currentWord.getWord_string());
            for (Meaning meaning : currentMeaningList) {
                meaningListModel.addElement(meaning.getWord_meaning());
            }
        } catch (ServerConnectException e) {
            showMessageDialog("服务器连接失败！");
        }
    }


    private void deleteMeaning(int index, long meaning_id) {
        try {
            Response response = DictionaryApi.delete_meaning(UserSession.LoginUser(), meaning_id);
            ApiResultModel apiResultModel = ApiResultModel.fromJson(response.getBody());
            showMessageDialog(apiResultModel.getMessage());
            if (apiResultModel.getCode() == ApiResultModel.SUCCESS_CODE) {
                meaningListModel.remove(index);
                currentMeaningList.remove(index);
            }
        } catch (ServerConnectException e) {
            showMessageDialog("服务器连接失败");
        }
    }

    private void deleteWord(long word_id) {
        try {
            Response response = DictionaryApi.delete_word(UserSession.LoginUser(), word_id);
            ApiResultModel apiResultModel = ApiResultModel.fromJson(response.getBody());
            showMessageDialog(apiResultModel.getMessage());
            if (apiResultModel.getCode() == ApiResultModel.SUCCESS_CODE) {
                wordText.setText("");
                meaningListModel.removeAllElements();
                loadNewWordList();
            }
        } catch (ServerConnectException e) {
            showMessageDialog("服务器连接失败");
        }
    }

    private void loadNewWordList() {
        try {
            Response response = DictionaryApi.get_new_words(NEW_WORD_NUM);
            ApiResultModel<List<Word>> apiResult = ApiResultModel.parseListResult(response.getBody(), Word.class);
            if (apiResult.getCode() == ApiResultModel.SUCCESS_CODE) {
                newWordList = apiResult.getResult();
                newWordListModel.removeAllElements();
                for (Word word : newWordList) {
                    newWordListModel.addElement(word.getWord_string());
                }
            }
        } catch (ServerConnectException e) {
            e.printStackTrace();
        }
    }

}
